package sf.jooq.dao;

import org.jooq.Condition;
import org.jooq.Delete;
import org.jooq.Insert;
import org.jooq.Record;
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.Table;
import org.jooq.Update;
import sf.common.wrapper.Page;
import sf.core.DBObject;
import sf.database.dao.DBClient;
import sf.database.jdbc.sql.Crud;
import sf.spring.util.Assert;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class DBJooqImpl implements DBJooq {
    protected DBClient client;

    public DBJooqImpl(DBClient client) {
        this.client = client;
    }

    @Override
    public <T extends DBObject> boolean jooqExists(SQLDialect sqlDialect, List<Condition> condition, Class<T> clz) {
        Assert.notNull(clz, "返回类型不能为空");
        //Class<?> clz = Jooq.getSelectFromTable(select);
        return client.executeFunc((conn -> Crud.getInstance().getJooqInf().jooqExists(conn, sqlDialect, condition, clz)));
    }

    @Override
    public <T> T jooqSelectOne(Select<?> select, Class<T> returnClass) {
        Assert.notNull(returnClass, "返回类型不能为空");
        //Class<?> clz = Jooq.getSelectFromTable(select);
        return client.executeFunc((conn -> Crud.getInstance().getJooqInf().jooqSelectOne(conn, select, returnClass)));
    }

    @Override
    public <T> List<T> jooqSelectList(Select<?> select, Class<T> returnClass) {
        Assert.notNull(returnClass, "返回类型不能为空");
        //Class<?> clz = Jooq.getSelectFromTable(select);
        return client.executeFunc((conn -> Crud.getInstance().getJooqInf().jooqSelectList(conn, select, returnClass)));
    }

    @Override
    public <T> Page<T> jooqSelectPage(Select<?> countSelect, Select<?> pageSelect, Class<T> returnClass) {
        Assert.notNull(returnClass, "返回类型不能为空");
//        Class<?> clz = Jooq.getSelectFromTable(select);
        return client.executeFunc((conn -> Crud.getInstance().getJooqInf().jooqSelectPage(conn, countSelect, pageSelect, returnClass)));
    }

    @Override
    public <T> void jooqSelectIterator(Consumer<Iterable<T>> ormIt, Class<T> beanClass, Select<?> select) {
        Assert.notNull(beanClass, "返回类型不能为空");
//        Class<?> clz = Jooq.getSelectFromTable(select);
        client.executeFunc((conn -> {
            Crud.getInstance().getJooqInf().selectIterator(conn, ormIt, select, beanClass);
            return null;
        }));
    }

    @Override
    public <T> void jooqSelectStream(Consumer<Stream<T>> ormStream, Class<T> beanClass, Select<?> select) {
        Assert.notNull(beanClass, "返回类型不能为空");
//        Class<?> clz = Jooq.getSelectFromTable(select);
        client.executeFunc((conn -> {
            Crud.getInstance().getJooqInf().selectStream(conn, ormStream, select, beanClass);
            return null;
        }));
    }

    @Override
    public <T extends Record> int jooqInsert(Insert<T> insert) {
        Assert.notNull(insert, "");
        Class<?> clz = null;
//        Table<?> table = JooqVisitor.getInsertTable(insert);
//        if (table != null && table instanceof JooqTable) {
//            clz = ((JooqTable<?>) table).getClz();
//        }
        return client.executeFunc((conn -> Crud.getInstance().getJooqInf().jooqInsert(conn, insert)));
    }

    @Override
    public <T extends Record> int jooqInsert(Insert<T> insert, Table<T> table, Map<String, Object> keyValues) {
        Assert.notNull(insert, "");
        Class<?> clz = null;
//        Table<?> table = JooqVisitor.getInsertTable(insert);
//        if (table != null && table instanceof JooqTable) {
//            clz = ((JooqTable<?>) table).getClz();
//        }
        return client.executeFunc((conn -> Crud.getInstance().getJooqInf().jooqInsert(conn, insert, table, keyValues)));
    }

    @Override
    public <T extends Record> int jooqUpdate(Update<T> update) {
        Assert.notNull(update, "");
        Class<?> clz = null;
//        Table<?> table = JooqVisitor.getUpdateTable(update);
//        if (table != null && table instanceof JooqTable) {
//            clz = ((JooqTable<?>) table).getClz();
//        }
        return client.executeFunc((conn -> Crud.getInstance().getJooqInf().jooqUpdate(conn, update)));
    }

    @Override
    public <T extends Record> int jooqDelect(Delete<T> delete) {
        Assert.notNull(delete, "");
        Class<?> clz = null;
//        Table<?> table = JooqVisitor.getDeleteTable(delete);
//        if (table != null && table instanceof JooqTable) {
//            clz = ((JooqTable<?>) table).getClz();
//        }
        return client.executeFunc((conn -> Crud.getInstance().getJooqInf().jooqDelect(conn, delete)));
    }
}
